home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1993 July / InfoMagic USENET CD-ROM July 1993.ISO / sources / unix / volume25 / hostcvt < prev    next >
Encoding:
Text File  |  1992-01-03  |  33.9 KB  |  1,418 lines

  1. Newsgroups: comp.sources.unix
  2. From: rogers@amadeus.wr.tek.com (Roger S. Southwick)
  3. Subject: v25i093: hostcvt - convert /etc/hosts files into DNS zone files
  4. Sender: sources-moderator@pa.dec.com
  5. Approved: vixie@pa.dec.com
  6.  
  7. Submitted-By: rogers@amadeus.wr.tek.com (Roger S. Southwick)
  8. Posting-Number: Volume 25, Issue 93
  9. Archive-Name: hostcvt
  10.  
  11. Here is a couple of programs for converting /etc/hosts files
  12. into files useful for the BIND Nameserver.
  13.  
  14.     Roger S. Southwick
  15.     rogers@amadeus.wr.tek.com
  16.  
  17. #! /bin/sh
  18. # This is a shell archive.  Remove anything before this line, then unpack
  19. # it by saving it into a file and typing "sh file".  To overwrite existing
  20. # files, type "sh file -c".  You can also feed this as standard input via
  21. # unshar, or by typing "sh <file", e.g..  If this archive is complete, you
  22. # will see the following message at the end:
  23. #        "End of archive 1 (of 1)."
  24. # Contents:  Makefile README egetopt.c gethostent.c hostcvt.8 main.c
  25. #   nextserial.8 nextserial.c
  26. # Wrapped by rogers@fangorn on Mon Nov 25 18:08:11 1991
  27. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  28. if test -f Makefile -a "${1}" != "-c" ; then 
  29.   echo shar: Will not over-write existing file \"Makefile\"
  30. else
  31. echo shar: Extracting \"Makefile\" \(972 characters\)
  32. sed "s/^X//" >Makefile <<'END_OF_Makefile'
  33. X#
  34. X# Makefile for hostcvt and nextserial
  35. X#
  36. X# $Id: Makefile,v 1.4 91/11/25 17:44:43 rogers Release $
  37. X#
  38. X
  39. XBINDIR = /etc/named_data/bin
  40. XMANDIR = /usr/manl/man8
  41. X
  42. XCFLAGS = -O
  43. XLDFLAGS = -s
  44. X
  45. Xall : hostcvt nextserial
  46. X
  47. Xhostcvt : main.o gethostent.o egetopt.o
  48. X    cc $(LDFLAGS) -o hostcvt main.o gethostent.o egetopt.o
  49. X
  50. Xnextserial : nextserial.c
  51. X    cc $(CFLAGS) $(LDFLAGS) -o nextserial nextserial.c
  52. X
  53. Xegetopt : egetopt.c
  54. X    cc $(CFLAGS) $(LDFLAGS) -c egetopt.c
  55. X
  56. X
  57. Xinstall : $(BINDIR)/hostcvt $(BINDIR)/nextserial \
  58. X    $(MANDIR)/hostcvt.8 $(MANDIR)/nextserial.8
  59. X
  60. X$(BINDIR)/hostcvt : hostcvt
  61. X    install -c -m 0755 hostcvt $(BINDIR)
  62. X
  63. X$(BINDIR)/nextserial : nextserial
  64. X    install -c -m 0755 nextserial $(BINDIR)
  65. X
  66. X$(MANDIR)/hostcvt.8 : hostcvt.8
  67. X    install -c -m 0644 hostcvt.8 $(MANDIR)
  68. X
  69. X$(MANDIR)/nextserial.8 : nextserial.8
  70. X    install -c -m 0644 nextserial.8 $(MANDIR)
  71. X
  72. Xlint : main.c gethostent.c nextserial.c
  73. X    lint main.c gethostent.c
  74. X    lint nextserial.c
  75. X
  76. Xclean :
  77. X    rm -f hostcvt nextserial *.o make.out
  78. X
  79. END_OF_Makefile
  80. if test 972 -ne `wc -c <Makefile`; then
  81.     echo shar: \"Makefile\" unpacked with wrong size!
  82. fi
  83. # end of overwriting check
  84. fi
  85. if test -f README -a "${1}" != "-c" ; then 
  86.   echo shar: Will not over-write existing file \"README\"
  87. else
  88. echo shar: Extracting \"README\" \(498 characters\)
  89. sed "s/^X//" >README <<'END_OF_README'
  90. XPrograms to convert /etc/hosts files into BIND files.
  91. X
  92. XNo warrenty written or implied.  You are free to use this program
  93. Xas long as you don't make money with it.  If you find bugs or
  94. Xmake enhancements, please send me a patch file.
  95. X
  96. XMany thanks to Mark Frost (mfrost@pyramid.com) who modified
  97. Xthe code to handle multiple domains and different files.
  98. X
  99. X    -Roger      (rogers@amadeus.wr.tek.com)
  100. X        UUCP:    ...!uunet!tektronix!amadeus.wr.tek.com!rogers
  101. X        ARPA:    <@RELAY.CS.NET:rogers@amadeus.wr.tek.com>
  102. END_OF_README
  103. if test 498 -ne `wc -c <README`; then
  104.     echo shar: \"README\" unpacked with wrong size!
  105. fi
  106. # end of overwriting check
  107. fi
  108. if test -f egetopt.c -a "${1}" != "-c" ; then 
  109.   echo shar: Will not over-write existing file \"egetopt.c\"
  110. else
  111. echo shar: Extracting \"egetopt.c\" \(6954 characters\)
  112. sed "s/^X//" >egetopt.c <<'END_OF_egetopt.c'
  113. X/*
  114. X * egetopt.c -- Extended 'getopt'.
  115. X *
  116. X * A while back, a public-domain version of getopt() was posted to the
  117. X * net.  A bit later, a gentleman by the name of Keith Bostic made some
  118. X * enhancements and reposted it.
  119. X *
  120. X * In recent weeks (i.e., early-to-mid 1988) there's been some
  121. X * heated discussion in comp.lang.c about the merits and drawbacks
  122. X * of getopt(), especially with regard to its handling of '?'.
  123. X *
  124. X * In light of this, I have taken Mr. Bostic's public-domain getopt()
  125. X * and have made some changes that I hope will be considered to be
  126. X * improvements.  I call this routine 'egetopt' ("Extended getopt").
  127. X * The default behavior of this routine is the same as that of getopt(),
  128. X * but it has some optional features that make it more useful.  These
  129. X * options are controlled by the settings of some global variables.
  130. X * By not setting any of these extra global variables, you will have
  131. X * the same functionality as getopt(), which should satisfy those
  132. X * purists who believe getopt() is perfect and can never be improved.
  133. X * If, on the other hand, you are someone who isn't satisfied with the
  134. X * status quo, egetopt() may very well give you the added capabilities
  135. X * you want.
  136. X *
  137. X * Look at the enclosed README file for a description of egetopt()'s
  138. X * new features.
  139. X *
  140. X * The code was originally posted to the net as getopt.c by ...
  141. X *
  142. X *    Keith Bostic
  143. X *    ARPA: keith@seismo 
  144. X *    UUCP: seismo!keith
  145. X *
  146. X * Current version: added enhancements and comments, reformatted code.
  147. X *
  148. X *    Lloyd Zusman
  149. X *    Master Byte Software
  150. X *    Los Gatos, California
  151. X *    Internet:    ljz@fx.com
  152. X *    UUCP:        ...!ames!fxgrp!ljz
  153. X *
  154. X *        May, 1988
  155. X */
  156. X
  157. X#ifndef lint
  158. Xstatic char *RCSid = "$Id: egetopt.c,v 1.1 91/11/25 17:45:07 rogers Release $";
  159. X#endif
  160. X
  161. X/*
  162. X * If you want, include stdio.h or something where EOF and NULL are defined.
  163. X * However, egetopt() is written so as not to need stdio.h, which should
  164. X * make it significantly smaller on some systems.
  165. X */
  166. X
  167. X#ifndef EOF
  168. X# define EOF        (-1)
  169. X#endif /* ! EOF */
  170. X
  171. X#ifndef NULL
  172. X# define NULL        (char *)0
  173. X#endif /* ! NULL */
  174. X
  175. X/*
  176. X * None of these constants are referenced in the executable portion of
  177. X * the code ... their sole purpose is to initialize global variables.
  178. X */
  179. X#define BADCH        (int)'?'
  180. X#define NEEDSEP        (int)':'
  181. X#define MAYBESEP    (int)'\0'
  182. X#define ERRFD        2
  183. X#define EMSG        ""
  184. X#define START        "-"
  185. X
  186. X/*
  187. X * Here are all the pertinent global variables.
  188. X */
  189. Xint opterr = 1;        /* if true, output error message */
  190. Xint optind = 1;        /* index into parent argv vector */
  191. Xint optopt;        /* character checked for validity */
  192. Xint optbad = BADCH;    /* character returned on error */
  193. Xint optchar = 0;    /* character that begins returned option */
  194. Xint optneed = NEEDSEP;    /* flag for mandatory argument */
  195. Xint optmaybe = MAYBESEP;/* flag for optional argument */
  196. Xint opterrfd = ERRFD;    /* file descriptor for error text */
  197. Xchar *optarg;        /* argument associated with option */
  198. Xchar *optstart = START;    /* list of characters that start options */
  199. X
  200. X
  201. X/*
  202. X * Macros.
  203. X */
  204. X
  205. X/*
  206. X * Conditionally print out an error message and return (depends on the
  207. X * setting of 'opterr' and 'opterrfd').  Note that this version of
  208. X * TELL() doesn't require the existence of stdio.h.
  209. X */
  210. X#define TELL(S)    { \
  211. X    if (opterr && opterrfd >= 0) { \
  212. X        char option = optopt; \
  213. X        (void)write(opterrfd, *nargv, strlen(*nargv)); \
  214. X        (void)write(opterrfd, (S), strlen(S)); \
  215. X        (void)write(opterrfd, &option, 1); \
  216. X        (void)write(opterrfd, "\n", 1); \
  217. X    } \
  218. X    return (optbad); \
  219. X}
  220. X
  221. X/*
  222. X * This works similarly to index() and strchr().  I include it so that you
  223. X * don't need to be concerned as to which one your system has.
  224. X */
  225. Xstatic char *
  226. X_sindex(string, ch)
  227. Xchar *string;
  228. Xint ch;
  229. X{
  230. X    if (string != NULL) {
  231. X        for (; *string != '\0'; ++string) {
  232. X            if (*string == (char)ch) {
  233. X                return (string);
  234. X            }
  235. X        }
  236. X    }
  237. X
  238. X    return (NULL);
  239. X}
  240. X
  241. X/*
  242. X * Here it is:
  243. X */
  244. Xint
  245. Xegetopt(nargc, nargv, ostr)
  246. Xint nargc;
  247. Xchar **nargv;
  248. Xchar *ostr;
  249. X{
  250. X    static char *place = EMSG;    /* option letter processing */
  251. X    register char *oli;        /* option letter list index */
  252. X    register char *osi = NULL;    /* option start list index */
  253. X
  254. X    if (nargv == (char **)NULL) {
  255. X        return (EOF);
  256. X    }
  257. X
  258. X    if (nargc <= optind || nargv[optind] == NULL) {
  259. X        return (EOF);
  260. X    }
  261. X
  262. X    if (place == NULL) {
  263. X        place = EMSG;
  264. X    }
  265. X
  266. X    /*
  267. X     * Update scanning pointer.
  268. X     */
  269. X    if (*place == '\0') {
  270. X        place = nargv[optind];
  271. X        if (place == NULL) {
  272. X            return (EOF);
  273. X        }
  274. X        osi = _sindex(optstart, *place);
  275. X        if (osi != NULL) {
  276. X            optchar = (int)*osi;
  277. X        }
  278. X        if (optind >= nargc || osi == NULL || *++place == '\0') {
  279. X                return (EOF);
  280. X        }
  281. X
  282. X        /*
  283. X         * Two adjacent, identical flag characters were found.
  284. X         * This takes care of "--", for example.
  285. X         */
  286. X        if (*place == place[-1]) {
  287. X            ++optind;
  288. X            return (EOF);
  289. X        }
  290. X    }
  291. X
  292. X    /*
  293. X     * If the option is a separator or the option isn't in the list,
  294. X     * we've got an error.
  295. X     */
  296. X    optopt = (int)*place++;
  297. X    oli = _sindex(ostr, optopt);
  298. X    if (optopt == optneed || optopt == optmaybe || oli == NULL) {
  299. X        /*
  300. X         * If we're at the end of the current argument, bump the
  301. X         * argument index.
  302. X         */
  303. X        if (*place == '\0') {
  304. X            ++optind;
  305. X        }
  306. X        TELL(": illegal option -- ");    /* byebye */
  307. X    }
  308. X
  309. X    /*
  310. X     * If there is no argument indicator, then we don't even try to
  311. X     * return an argument.
  312. X     */
  313. X    ++oli;
  314. X    if (*oli == '\0' || (*oli != optneed && *oli != optmaybe)) {
  315. X        /*
  316. X         * If we're at the end of the current argument, bump the
  317. X         * argument index.
  318. X         */
  319. X        if (*place == '\0') {
  320. X            ++optind;
  321. X        }
  322. X        optarg = NULL;
  323. X    }
  324. X    /*
  325. X     * If we're here, there's an argument indicator.  It's handled
  326. X     * differently depending on whether it's a mandatory or an
  327. X     * optional argument.
  328. X     */
  329. X    else {
  330. X        /*
  331. X         * If there's no white space, use the rest of the
  332. X         * string as the argument.  In this case, it doesn't
  333. X         * matter if the argument is mandatory or optional.
  334. X         */
  335. X        if (*place != '\0') {
  336. X            optarg = place;
  337. X        }
  338. X        /*
  339. X         * If we're here, there's whitespace after the option.
  340. X         *
  341. X         * Is it a mandatory argument?  If so, return the
  342. X         * next command-line argument if there is one.
  343. X         */
  344. X        else if (*oli == optneed) {
  345. X            /*
  346. X             * If we're at the end of the argument list, there
  347. X             * isn't an argument and hence we have an error.
  348. X             * Otherwise, make 'optarg' point to the argument.
  349. X             */
  350. X            if (nargc <= ++optind) {
  351. X                place = EMSG;
  352. X                TELL(": option requires an argument -- ");
  353. X            }
  354. X            else {
  355. X                optarg = nargv[optind];
  356. X            }
  357. X        }
  358. X        /*
  359. X         * If we're here it must have been an optional argument.
  360. X         */
  361. X        else {
  362. X            if (nargc <= ++optind) {
  363. X                place = EMSG;
  364. X                optarg = NULL;
  365. X            }
  366. X            else {
  367. X                optarg = nargv[optind];
  368. X                if (optarg == NULL) {
  369. X                    place = EMSG;
  370. X                }
  371. X                /*
  372. X                 * If the next item begins with a flag
  373. X                 * character, we treat it like a new
  374. X                 * argument.  This is accomplished by
  375. X                 * decrementing 'optind' and returning
  376. X                 * a null argument.
  377. X                 */
  378. X                else if (_sindex(optstart, *optarg) != NULL) {
  379. X                    --optind;
  380. X                    optarg = NULL;
  381. X                }
  382. X            }
  383. X        }
  384. X        place = EMSG;
  385. X        ++optind;
  386. X    }
  387. X
  388. X    /*
  389. X     * Return option letter.
  390. X     */
  391. X    return (optopt);
  392. X}
  393. END_OF_egetopt.c
  394. if test 6954 -ne `wc -c <egetopt.c`; then
  395.     echo shar: \"egetopt.c\" unpacked with wrong size!
  396. fi
  397. # end of overwriting check
  398. fi
  399. if test -f gethostent.c -a "${1}" != "-c" ; then 
  400.   echo shar: Will not over-write existing file \"gethostent.c\"
  401. else
  402. echo shar: Extracting \"gethostent.c\" \(2771 characters\)
  403. sed "s/^X//" >gethostent.c <<'END_OF_gethostent.c'
  404. X/*
  405. X * Copyright (c) 1983 Regents of the University of California.
  406. X * All rights reserved.
  407. X *
  408. X * Redistribution and use in source and binary forms are permitted
  409. X * provided that the above copyright notice and this paragraph are
  410. X * duplicated in all such forms and that any documentation,
  411. X * advertising materials, and other materials related to such
  412. X * distribution and use acknowledge that the software was developed
  413. X * by the University of California, Berkeley.  The name of the
  414. X * University may not be used to endorse or promote products derived
  415. X * from this software without specific prior written permission.
  416. X * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
  417. X * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
  418. X * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  419. X */
  420. X
  421. X#include <stdio.h>
  422. X#include <sys/types.h>
  423. X#include <sys/socket.h>
  424. X#include <netdb.h>
  425. X#include <ctype.h>
  426. X
  427. X#ifndef lint
  428. Xstatic char *RCSid = "$Id: gethostent.c,v 1.2 90/10/03 22:50:29 rogers Release $";
  429. X#endif
  430. X
  431. X/*
  432. X * Internet version.
  433. X */
  434. X#define    MAXALIASES    35
  435. X#define    MAXADDRSIZE    14
  436. X
  437. Xstatic FILE *hostf = NULL;
  438. Xstatic char line[BUFSIZ+1];
  439. Xstatic char hostaddr[MAXADDRSIZE];
  440. Xstatic struct hostent host;
  441. Xstatic char *host_aliases[MAXALIASES];
  442. Xstatic char *host_addrs[] = {
  443. X    hostaddr,
  444. X    NULL
  445. X};
  446. X
  447. X/*
  448. X * The following is shared with gethostnamadr.c
  449. X */
  450. X
  451. Xstatic char *any();
  452. X
  453. X#ifdef NOTUSEDINHOSTCVT
  454. X
  455. Xmysethostent()
  456. X{
  457. X    if (hostf != NULL)
  458. X        rewind(hostf);
  459. X}
  460. X
  461. Xmyendhostent()
  462. X{
  463. X    if (hostf != NULL) {
  464. X        (void)fclose(hostf);
  465. X        hostf = NULL;
  466. X    }
  467. X}
  468. X#endif  /* NOTUSEDINHOSTCVT */
  469. X
  470. Xstruct hostent *
  471. Xmygethostent(fname)
  472. Xchar *fname;
  473. X{
  474. X    u_long inet_addr();
  475. X    char *p;
  476. X    register char *cp, **q;
  477. X
  478. X    if (hostf == NULL && (hostf = fopen(fname, "r" )) == NULL)
  479. X        return (NULL);
  480. Xagain:
  481. X    if ((p = fgets(line, BUFSIZ, hostf)) == NULL)
  482. X        return (NULL);
  483. X    if (*p == '#')
  484. X        goto again;
  485. X    cp = any(p, "#\n");
  486. X    if (cp == NULL)
  487. X        goto again;
  488. X    *cp = '\0';
  489. X    cp = any(p, " \t");
  490. X    if (cp == NULL)
  491. X        goto again;
  492. X    *cp++ = '\0';
  493. X    /* THIS STUFF IS INTERNET SPECIFIC */
  494. X    host.h_addr_list = host_addrs;
  495. X    *((u_long *)host.h_addr) = inet_addr(p);
  496. X    host.h_length = sizeof (u_long);
  497. X    host.h_addrtype = AF_INET;
  498. X    while (*cp == ' ' || *cp == '\t')
  499. X        cp++;
  500. X    host.h_name = cp;
  501. X    q = host.h_aliases = host_aliases;
  502. X    cp = any(cp, " \t");
  503. X    if (cp != NULL) 
  504. X        *cp++ = '\0';
  505. X    while (cp && *cp) {
  506. X        if (*cp == ' ' || *cp == '\t') {
  507. X            cp++;
  508. X            continue;
  509. X        }
  510. X        if (q < &host_aliases[MAXALIASES - 1])
  511. X            *q++ = cp;
  512. X        cp = any(cp, " \t");
  513. X        if (cp != NULL)
  514. X            *cp++ = '\0';
  515. X    }
  516. X    *q = NULL;
  517. X    return (&host);
  518. X}
  519. X
  520. Xstatic char *
  521. Xany(cp, match)
  522. X    register char *cp;
  523. X    char *match;
  524. X{
  525. X    register char *mp, c;
  526. X
  527. X    while (c = *cp) {
  528. X        for (mp = match; *mp; mp++)
  529. X            if (*mp == c)
  530. X                return (cp);
  531. X        cp++;
  532. X    }
  533. X    return ((char *)0);
  534. X}
  535. END_OF_gethostent.c
  536. if test 2771 -ne `wc -c <gethostent.c`; then
  537.     echo shar: \"gethostent.c\" unpacked with wrong size!
  538. fi
  539. # end of overwriting check
  540. fi
  541. if test -f hostcvt.8 -a "${1}" != "-c" ; then 
  542.   echo shar: Will not over-write existing file \"hostcvt.8\"
  543. else
  544. echo shar: Extracting \"hostcvt.8\" \(4360 characters\)
  545. sed "s/^X//" >hostcvt.8 <<'END_OF_hostcvt.8'
  546. X.\"
  547. X.\" $Id: hostcvt.8,v 1.2 91/11/25 17:45:24 rogers Release $
  548. X.\"
  549. X.TH HOSTCVT 8 "10-3-90"
  550. X.SH NAME
  551. Xhostcvt - Convert hosts(5) file to BIND files
  552. X.SH SYNOPSIS
  553. X.B hostcvt
  554. X[ -s
  555. X.I soabasefile
  556. X] [ -n
  557. X.I netfile
  558. X]
  559. X[ -h
  560. X.I hostfile
  561. X]
  562. X.br
  563. X   [ -o
  564. X.I outputfile
  565. X] domain
  566. X.SH DESCRIPTION
  567. X.LP
  568. X.I hostcvt
  569. Xreads a hosts(5) file specified by the
  570. X.I hostfile
  571. Xargument ("hosts.thisdomain" by default), and converts them to
  572. XBIND hostname-to-address and reverse tables for the argument
  573. X.I
  574. Xdomain.
  575. XThe names of the reverse files are specified in the argument
  576. X.I netfile
  577. X("netlist" by default).
  578. XIf no output file is specified, the hostname to address table is put
  579. Xinto a file in the current directory named
  580. X.I domain.
  581. XAll files are prepended with the
  582. X.I soabasefile
  583. X("soabasefile" by default) which is the SOA record for this domain (see example
  584. Xbelow).
  585. X.LP
  586. X.B Hostcvt
  587. Xissues warnings for any duplicated names (name to name, name to
  588. Xaliases, aliases to name and aliases to aliases) and will only allow
  589. Xthe first instance of a name from
  590. X.I hostsfile
  591. Xto be in the outputfile and the reverse table files. Lines in
  592. X.I hostsfile
  593. Xthat have an IP address but no hostname are ignored and a warning message is
  594. Xprinted.
  595. X.LP
  596. X.SH OPTIONS
  597. X.TP
  598. X.BI \-h " hostsfile"
  599. XSpecify a file in hosts(5) format to read hosts from. The default is
  600. X"hosts.thisdomain".
  601. X.TP
  602. X.BI \-n " netfile"
  603. XSpecify a
  604. X.I netfile.
  605. XThis file specifies the names of the reverse tables.  The default is "netlist".
  606. X.LP
  607. X.TP
  608. X.BI \-o " outputfile"
  609. XSpecify an output file for the hostname-to-address file. If unspecified, this
  610. Xfile is the same as
  611. X.I domainname.
  612. X.LP
  613. X.TP
  614. X.BI \-s " soabasefile"
  615. XSpecify an SOA file. The default is "soabasefile".
  616. X.SH "FORMAT OF THE NETLIST FILE"
  617. X.LP
  618. X.I netfile
  619. Xhas the format:
  620. X.RS
  621. X.nf
  622. X
  623. Xnetportion file
  624. X.fi
  625. X.RE
  626. X.LP
  627. XThe
  628. X.I netportion
  629. Xdescribes the portion of the address field which hostcvt is to pay attention
  630. Xto.  The 
  631. X.I netportion
  632. Xshould be all digits and dots necessary to do a strncmp() against the
  633. Xaddress portion of
  634. X.I hostsfile,
  635. Xtaking into account how the
  636. X.I named.boot
  637. Xfile is set up for the reverse address translation.
  638. X.LP
  639. XThe
  640. X.I file
  641. Xis the path to the file the reverse address for this 
  642. X.I netportion.
  643. X.LP
  644. XFor example, suppose named.boot file has the following reverse translations:
  645. X.RS
  646. X.nf
  647. X
  648. Xprimary     36.in-addr.arpa         net/net36
  649. Xprimary     0.101.in-addr.arpa      net/net101
  650. Xprimary     0.0.100.in-addr.arpa    net/net127
  651. Xprimary     63.134.in-addr.arpa     reversefile
  652. X.fi
  653. X.RE
  654. X.LP
  655. XFor the net 36 addresses, the
  656. X.I hostsfile
  657. Xwould have entries of 36.xx.yy.zz, where all three lower portions 
  658. Xwould be used.  For the net 101 addresses, the 
  659. X.I hosts.thisdomain
  660. Xfile would have 101.0.yy.zz entries.  And so forth.
  661. X.LP
  662. XThe corresponding
  663. X.I netfile
  664. Xwould show:
  665. X.RS
  666. X.nf
  667. X
  668. X36.         net/net36
  669. X101.0.      net/net101
  670. X100.0.0.    net/net100
  671. X134.63.     reversefile
  672. X.fi
  673. X.RE
  674. X.LP
  675. XIt is VERY important that the trailing dot be in the
  676. X.I netportion
  677. Xof the 
  678. X.I netfile.
  679. XThe program does a strncmp() against the host address field of
  680. X.I hostsfile
  681. Xusing the 
  682. X.I netportion
  683. Xstring and it's length to get the exact match (O.K., so the program is
  684. Xa hack).
  685. X.LP
  686. X.B Hostcvt
  687. Xignores lines starting with a # (pound sign) or empty (i.e. ^$ in egrep terms)
  688. Xlines  in the
  689. X.I netlist
  690. Xfile.  These may be used for comments or separation.
  691. X.SH "FORMAT OF THE SOABASEFILE"
  692. X.LP
  693. XThe
  694. X.I soabasefile
  695. Xis the SOA record which is prepended to all output files, and should
  696. Xbe a valid SOA format.  Here is the 
  697. X.I soabasefile
  698. Xfor our domain (wr.tek.com):
  699. X.RS
  700. X.nf
  701. X
  702. X@    IN    SOA    wrgate.wr.tek.com.    wrap.wrgate.wr.tek.com. (
  703. X                1    ; Serial
  704. X                3600    ; Refresh
  705. X                300    ; Retry
  706. X                3600000    ; Expire
  707. X                14400 )    ; Minimum
  708. X        IN    NS    wrgate.wr.tek.com.
  709. X.fi
  710. X.RE
  711. X.LP
  712. XNote that the Serial number in the 
  713. X.I soabasefile
  714. Xshould be advanced before
  715. X.B hostcvt
  716. Xis run, rather than trying to change all the SOA records in the resulting
  717. Xfiles.  The 
  718. X.B nextserial
  719. Xprogram is a convenient tool for changing the Serial numbers in files.
  720. X.SH "EXAMPLE USAGE"
  721. X.LP
  722. XThe following is what I do to convert my
  723. X.I hostsfile
  724. Xinto files for my domain:
  725. X.RS
  726. X.nf
  727. Xnextserial soabasefile
  728. Xhostcvt -s soabasefile wr.tek.com
  729. X.fi
  730. X.RE
  731. X.SH "SEE ALSO"
  732. Xhosts(5), nextserial(8)
  733. X.SH BUGS
  734. XIt would also be nice to retain comments made in
  735. X.I hostsfile.
  736. X.LP
  737. X.SH AUTHOR
  738. XRoger S. Southwick
  739. X.br
  740. Xrogers@amadeus.wr.tek.com
  741. X.LP
  742. XModifications by Mark Frost
  743. X.br
  744. Xmfrost@pyramid.com
  745. END_OF_hostcvt.8
  746. if test 4360 -ne `wc -c <hostcvt.8`; then
  747.     echo shar: \"hostcvt.8\" unpacked with wrong size!
  748. fi
  749. # end of overwriting check
  750. fi
  751. if test -f main.c -a "${1}" != "-c" ; then 
  752.   echo shar: Will not over-write existing file \"main.c\"
  753. else
  754. echo shar: Extracting \"main.c\" \(10143 characters\)
  755. sed "s/^X//" >main.c <<'END_OF_main.c'
  756. X#include <stdio.h>
  757. X#include <sys/types.h>
  758. X#include <sys/socket.h>
  759. X#include <netinet/in.h>
  760. X#include <arpa/inet.h>
  761. X#include <netdb.h>
  762. X#include <sys/stat.h>
  763. X#include <sys/file.h>
  764. X
  765. X#ifndef lint
  766. Xstatic char *RCSid = "$Id: main.c,v 1.4 91/11/25 17:46:06 rogers Release $";
  767. X
  768. X#endif
  769. X
  770. Xstruct netlist {
  771. X    char *nl_net;        /* Net number portion     */
  772. X    int nl_netlen;        /* Length of above     */
  773. X    char *nl_file;        /* File name          */
  774. X    FILE *nl_fp;        /* Pointer to above     */
  775. X    struct netlist *nl_next;    /* Next one         */
  776. X};
  777. X
  778. Xtypedef struct netlist nl_t;
  779. Xtypedef struct netlist *nl_tp;
  780. X
  781. Xstruct host_names {
  782. X    char *h_name;
  783. X    char **h_aliases;
  784. X    struct host_names *h_next;
  785. X};
  786. X
  787. Xtypedef struct host_names hn_t;
  788. Xtypedef struct host_names *hn_tp;
  789. X
  790. Xchar *soa = NULL;        /* The soa from argv[]         */
  791. Xchar *domain = NULL;        /* Domain name from argv[]     */
  792. Xnl_tp ntop = NULL;        /* Top of linked list         */
  793. Xhn_tp hntop = NULL;        /* Top of list of hostnames     */
  794. Xchar *hostsfile, *netfile, *soafile, *outputfile;
  795. Xextern char *optarg;        /* for egetopt() */
  796. X
  797. Xextern int optind;        /* for egetopt() */
  798. Xextern int errno;
  799. Xextern char *sys_errlist[];
  800. X
  801. X#define ERR    sys_errlist[errno], errno
  802. X
  803. Xvoid exit();
  804. X
  805. Xmain(argc, argv)
  806. Xint argc;
  807. Xchar *argv[];
  808. X{
  809. X    FILE *fopen();
  810. X    char *strsave(), *malloc();
  811. X    struct hostent *mygethostent();
  812. X    register struct hostent *hp;
  813. X    register FILE *fp;
  814. X    register char *ipaddr, **cpp;
  815. X    register nl_tp np;
  816. X    struct in_addr foo;
  817. X
  818. X    char ch;
  819. X    int hostflag, soaflag, netflag, errflag, outputflag, domainflag;
  820. X
  821. X    hostflag = soaflag = netflag = errflag = outputflag = domainflag = 0;
  822. X    hostsfile = soafile = netfile = domain = outputfile = NULL;
  823. X
  824. X
  825. X    while ((ch = egetopt(argc, argv, "h:n:o:s:")) != -1)
  826. X    switch (ch) {
  827. X        case 'h':        /* assign name for "hosts" file (sourcefile) */
  828. X        if (hostflag){
  829. X            errflag++;
  830. X        }
  831. X        else {
  832. X            hostsfile = strsave(optarg);
  833. X            hostflag++;
  834. X        }
  835. X        break;
  836. X
  837. X        case 'n':        /* assign name for "netlist" */
  838. X        if (netflag){
  839. X            errflag++;
  840. X        }
  841. X        else {
  842. X            netfile = strsave(optarg);
  843. X            netflag++;
  844. X        }
  845. X        break;
  846. X
  847. X        case 'o':        /* assign name for main output file */
  848. X        if (outputflag){
  849. X            errflag++;
  850. X        }
  851. X        else {
  852. X            outputfile = strsave(optarg);
  853. X            outputflag++;
  854. X        }
  855. X        break;
  856. X
  857. X        case 's':        /* assign name for "soabasefile" */
  858. X        if (soaflag){
  859. X            errflag++;
  860. X        }
  861. X        else {
  862. X            soafile = strsave(optarg);
  863. X            soaflag++;
  864. X        }
  865. X        break;
  866. X
  867. X        case '?':        /* anything else that might show up */
  868. X        errflag++;
  869. X
  870. X    }            /* switch */
  871. X
  872. X    for (; optind < argc; optind++) {
  873. X    if (domainflag) {
  874. X        errflag++;
  875. X        break;
  876. X    }            /* if */
  877. X    else {
  878. X        domain = strsave(argv[optind]);
  879. X        domainflag++;
  880. X    }            /* else */
  881. X    }                /* for */
  882. X
  883. X    if (errflag || domain == NULL || (strlen(domain) < 2)) {
  884. X    (void) fprintf(stderr, "usage: hostcvt [-h hostsfile] [-n netlistfile]\n\t\t[-s soabasefile] [-o outputfile] domain\n");
  885. X    exit(2);
  886. X    }
  887. X
  888. X    if (!netflag){
  889. X    netfile = strsave("netlist");
  890. X    }
  891. X
  892. X    if (!hostflag){
  893. X    hostsfile = strsave("hosts.thisdomain");
  894. X    }
  895. X
  896. X    if (!soafile) {
  897. X    soafile = strsave("soabasefile");
  898. X    }
  899. X    if (!outputflag){
  900. X    outputfile = domain;
  901. X    }
  902. X
  903. X    rdsoa(soafile);
  904. X
  905. X    (void)close(0);
  906. X    (void)close(1);
  907. X
  908. X    if((fp = fopen(outputfile, "w")) == NULL) {
  909. X    (void) fprintf(stderr, "hostcvt: could not open %s\n", outputfile);
  910. X    exit(1);
  911. X    }
  912. X
  913. X    if(access(hostsfile, R_OK) == -1) {
  914. X    (void) fprintf(stderr, "hostcvt: no host file %s\n", hostsfile);
  915. X    exit(1);
  916. X    }
  917. X
  918. X    if(soa != NULL) {
  919. X    (void) fputs(soa, fp);
  920. X    }
  921. X
  922. X    rdnetlist();
  923. X
  924. X    while ((hp = mygethostent(hostsfile)) != NULL) {
  925. X    foo.s_addr = (u_long) * ((u_long *) hp->h_addr);
  926. X    ipaddr = inet_ntoa(foo);
  927. X    if (outnet(ipaddr, hp->h_name)) {
  928. X
  929. X        if (isdup(hp)){
  930. X        continue;
  931. X        }
  932. X
  933. X        if (strlen(hp->h_name) == 0) {
  934. X        (void)fprintf(stderr, "No name found for %s -- ignoring...\n", ipaddr);
  935. X        }
  936. X        else {
  937. X        savehp(hp);
  938. X
  939. X        (void) fprintf(fp, "%s\t\tIN\tA\t%s\n", hp->h_name, ipaddr);
  940. X
  941. X        for (cpp = hp->h_aliases; *cpp != NULL; cpp++) {
  942. X            if (strcasecmp(*cpp, hp->h_name) != 0) {
  943. X            (void) fprintf(fp, "%s\t\tIN\tCNAME\t%s\n", *cpp, hp->h_name);
  944. X            }
  945. X        }        /* else */
  946. X        }
  947. X    }
  948. X    }
  949. X    (void) fflush(fp);
  950. X    (void) fclose(fp);
  951. X    for (np = ntop; np != NULL; np = np->nl_next) {
  952. X    (void) fflush(np->nl_fp);
  953. X    (void) fclose(np->nl_fp);
  954. X    }
  955. X
  956. X    return(0);
  957. X}
  958. X
  959. X/*
  960. X * See if the new hostname or any of it's aliases
  961. X * are already known.
  962. X */
  963. X
  964. Xint
  965. Xisdup(hp)
  966. Xregister struct hostent *hp;
  967. X{
  968. X    register hn_tp np;
  969. X    register char **cpp, **acp;
  970. X
  971. X    /*
  972. X     * For each node in our linked list of known names....
  973. X     */
  974. X
  975. X    for (np = hntop; np != NULL; np = np->h_next) {
  976. X
  977. X    /*
  978. X     * See if the new name matches directly
  979. X     */
  980. X
  981. X    if (strcasecmp(hp->h_name, np->h_name) == 0) {
  982. X        (void) fprintf(stderr, "hostcvt: duplicated name: %s\n", hp->h_name);
  983. X        return (1);
  984. X    }
  985. X
  986. X    /*
  987. X     * See if the new name matches an alias
  988. X     */
  989. X
  990. X    for (acp = np->h_aliases; *acp != NULL; acp++) {
  991. X        if (strcasecmp(hp->h_name, *acp) == 0) {
  992. X        (void) fprintf(stderr, "hostcvt: duplicated name to alias: %s\n", hp->h_name);
  993. X        return (1);
  994. X        }
  995. X    }
  996. X
  997. X    /*
  998. X     * For each of the new machines aliases
  999. X     */
  1000. X
  1001. X    for (cpp = hp->h_aliases; *cpp != NULL; cpp++) {
  1002. X
  1003. X        /*
  1004. X         * See if the alias matches the real name
  1005. X         */
  1006. X
  1007. X        if (strcasecmp(*cpp, np->h_name) == 0) {
  1008. X        (void) fprintf(stderr, "hostcvt: duplicated alias to name: %s\n", hp->h_name);
  1009. X        return (1);
  1010. X        }
  1011. X
  1012. X        /*
  1013. X         * See if the alias matches one of our aliases
  1014. X         */
  1015. X
  1016. X        for (acp = np->h_aliases; *acp != NULL; acp++) {
  1017. X        if (strcasecmp(*acp, *cpp) == 0) {
  1018. X            (void) fprintf(stderr, "hostcvt: duplicated alias to alias: %s\n", hp->h_name);
  1019. X            return (1);
  1020. X        }
  1021. X        }
  1022. X    }
  1023. X    }
  1024. X
  1025. X    return (0);            /* No match     */
  1026. X}
  1027. X
  1028. Xsavehp(hp)
  1029. Xregister struct hostent *hp;
  1030. X{
  1031. X    char *malloc(), *strsave();
  1032. X    register char **cpp, **acp;
  1033. X    register int cnt;
  1034. X    register hn_tp np;
  1035. X
  1036. X    if ((np = (hn_tp) malloc(sizeof(hn_t))) == NULL) {
  1037. X    (void) fprintf(stderr, "hostcvt: could not malloc in savehp()!\n");
  1038. X    exit(1);
  1039. X    }
  1040. X
  1041. X    np->h_name = strsave(hp->h_name);
  1042. X
  1043. X    for (cnt = 1, cpp = hp->h_aliases; *cpp != NULL; cpp++)
  1044. X    cnt++;
  1045. X
  1046. X    if ((np->h_aliases = (char **) malloc((unsigned) (cnt * sizeof(char **)))) == NULL) {
  1047. X    (void) fprintf(stderr, "hostcvt: could not malloc in savehp()!\n");
  1048. X    exit(1);
  1049. X    }
  1050. X
  1051. X    for (cpp = hp->h_aliases, acp = np->h_aliases; *cpp != NULL; cpp++, acp++) {
  1052. X    *acp = strsave(*cpp);
  1053. X    }
  1054. X    *acp = NULL;
  1055. X
  1056. X    np->h_next = hntop;
  1057. X    hntop = np;
  1058. X}
  1059. X
  1060. X/*
  1061. X * Add the host named "name" at the IP address "ip" to
  1062. X * the proper net file.  Return 1 if done OK, 0 if not.
  1063. X */
  1064. X
  1065. Xint
  1066. Xoutnet(ip, name)
  1067. Xchar *ip, *name;
  1068. X{
  1069. X    char *strcpy(), *index(), *strsave();
  1070. X    register nl_tp np;
  1071. X    register int i;
  1072. X    register char *last, *cp, *ipaddr;
  1073. X    char dig[4][20];
  1074. X
  1075. X    ipaddr = strsave(ip);
  1076. X
  1077. X    for (np = ntop; np != NULL; np = np->nl_next) {
  1078. X    if (strncmp(ipaddr, np->nl_net, np->nl_netlen) == 0) {
  1079. X        last = ipaddr + np->nl_netlen;
  1080. X        bzero((char *) dig, sizeof(dig));
  1081. X
  1082. X        for (i = 0; *last != '\0'; i++) {
  1083. X        if ((cp = index(last, '.')) == NULL){
  1084. X            break;
  1085. X        }
  1086. X
  1087. X        *cp = '\0';
  1088. X        (void) strcpy(dig[i], last);
  1089. X        last = cp + 1;
  1090. X        }
  1091. X
  1092. X        (void) fprintf(np->nl_fp, "%s", last);
  1093. X
  1094. X        for (i = 3; i >= 0; i--) {
  1095. X        if (dig[i][0] != '\0'){
  1096. X            (void) fprintf(np->nl_fp, ".%s", dig[i]);
  1097. X        }
  1098. X        }
  1099. X        (void) fprintf(np->nl_fp, "\t\tIN\tPTR\t%s.%s.\n", name, domain);
  1100. X        return (1);
  1101. X    }
  1102. X    }
  1103. X    (void) fprintf(stderr, "hostcvt: could not find file for %s (add= %s)\n", name, ipaddr);
  1104. X    return (0);
  1105. X}
  1106. X
  1107. Xrdnetlist()
  1108. X{
  1109. X    char *strsave(), *malloc(), *index();
  1110. X    FILE *fopen();
  1111. X    register FILE *fp;
  1112. X    register nl_tp np;
  1113. X    register int i, cnt;
  1114. X    char nbuf[256], fbuf[512], buf[BUFSIZ];
  1115. X
  1116. X    if ((fp = fopen(netfile, "r")) == NULL) {
  1117. X    (void) fprintf(stderr, "hostcvt: could not open %s\n", netfile);
  1118. X    exit(1);
  1119. X    }
  1120. X
  1121. X    for (i = 1, cnt = 0; fgets(buf, BUFSIZ, fp) != NULL; i++) {
  1122. X    if (buf[0] == '#' || buf[0] == '\n'){    /* allow comments and blanks     */
  1123. X        continue;
  1124. X    }
  1125. X
  1126. X    if (sscanf(buf, "%s %s", nbuf, fbuf) != 2) {
  1127. X        (void) fprintf(stderr, "hostcvt: error on line #%d in %s, contents= %s", i, netfile, buf);
  1128. X        continue;
  1129. X    }
  1130. X
  1131. X    if ((np = (nl_tp) malloc(sizeof(nl_t))) == NULL) {
  1132. X        (void) fprintf(stderr, "hostcvt: could not malloc!\n");
  1133. X        exit(1);
  1134. X    }
  1135. X    np->nl_net = strsave(nbuf);
  1136. X    np->nl_netlen = strlen(nbuf);
  1137. X    np->nl_file = strsave(fbuf);
  1138. X    np->nl_fp = NULL;
  1139. X    np->nl_next = ntop;
  1140. X    ntop = np;
  1141. X    cnt++;
  1142. X    }
  1143. X    (void) fclose(fp);
  1144. X
  1145. X    /*
  1146. X     * figure out how many open files we can have: Max (getdtablesize) minus:
  1147. X     * 1 for stderr (stdin & stdout closed) 1 for domain (output) file
  1148. X     * (argv[1])
  1149. X     */
  1150. X
  1151. X    i = getdtablesize() - 2;
  1152. X    if (cnt > i) {
  1153. X    (void) fprintf(stderr, "hostcvt: can not have more than %d entries (you have %d)\n", i, cnt);
  1154. X    exit(1);
  1155. X    }
  1156. X
  1157. X    for (np = ntop; np != NULL; np = np->nl_next) {
  1158. X    if ((np->nl_fp = fopen(np->nl_file, "w")) == NULL) {
  1159. X        (void) fprintf(stderr, "hostcvt: could not open %s for write\n", np->nl_file);
  1160. X        continue;
  1161. X    }
  1162. X    if (soa != NULL) {
  1163. X        (void) fputs(soa, np->nl_fp);
  1164. X    }
  1165. X    }
  1166. X}
  1167. X
  1168. Xrdsoa(file)
  1169. Xchar *file;
  1170. X{
  1171. X    int read(), open(), fstat();
  1172. X    register int fd, rv;
  1173. X    struct stat stb;
  1174. X
  1175. X    if ((fd = open(file, O_RDONLY, 0)) == -1) {
  1176. X    soa = NULL;
  1177. X    (void) fprintf(stderr, "hostcvt: could not open SOA file, skipping\n");
  1178. X    return;
  1179. X    }
  1180. X
  1181. X    if (fstat(fd, &stb) == -1) {
  1182. X    (void) fprintf(stderr, "hostcvt: could not fstat %s (%d)\n", ERR);
  1183. X    exit(1);
  1184. X    }
  1185. X
  1186. X    if ((soa = malloc((unsigned) stb.st_size)) == NULL) {
  1187. X    (void) fprintf(stderr, "hostcvt: could not malloc enough for SOA file (%s)\n", file);
  1188. X    exit(1);
  1189. X    }
  1190. X
  1191. X    if ((rv = read(fd, soa, (int) stb.st_size)) != stb.st_size) {
  1192. X    (void) fprintf(stderr, "hostcvt: asked to read %d, got %d", (int) stb.st_size, rv);
  1193. X    if (rv == -1){
  1194. X        (void) fprintf(stderr, " - %s (%d)", ERR);
  1195. X    }
  1196. X
  1197. X    (void) fprintf(stderr, "\n");
  1198. X    exit(1);
  1199. X    }
  1200. X
  1201. X    (void) close(fd);
  1202. X}
  1203. X
  1204. Xchar *
  1205. Xstrsave(str)
  1206. Xregister char *str;
  1207. X{
  1208. X    char *malloc(), *strcpy();
  1209. X    register char *cp;
  1210. X
  1211. X    if (str == NULL)
  1212. X    return (NULL);
  1213. X
  1214. X    if ((cp = malloc((unsigned) (strlen(str) + 1))) != NULL)
  1215. X    (void) strcpy(cp, str);
  1216. X
  1217. X    return (cp);
  1218. X}
  1219. END_OF_main.c
  1220. if test 10143 -ne `wc -c <main.c`; then
  1221.     echo shar: \"main.c\" unpacked with wrong size!
  1222. fi
  1223. # end of overwriting check
  1224. fi
  1225. if test -f nextserial.8 -a "${1}" != "-c" ; then 
  1226.   echo shar: Will not over-write existing file \"nextserial.8\"
  1227. else
  1228. echo shar: Extracting \"nextserial.8\" \(1311 characters\)
  1229. sed "s/^X//" >nextserial.8 <<'END_OF_nextserial.8'
  1230. X.\"
  1231. X.\" $Id: nextserial.8,v 1.1 90/10/03 23:34:03 rogers Release $
  1232. X.\"
  1233. X.TH NEXTSERIAL 8 "10-3-90"
  1234. X.SH NAME
  1235. Xnextserial - Increment the BIND SOA Serial number in a file
  1236. X.SH SYNOPSIS
  1237. X.B nextserial
  1238. X.I soafile
  1239. X.SH DESCRIPTION
  1240. X.LP
  1241. X.I nextserial
  1242. Xreads the
  1243. X.I soafile
  1244. Xfile for a line containing the (regular expression) pattern "Serial".
  1245. XThis line is assumed to be the line containing the SOA Serial 
  1246. Xnumber.  The number is read from the line and incremented.  The
  1247. Xline is then written with the new serial number.  All other lines
  1248. Xare put through unchanged.
  1249. X.SH "EXAMPLE"
  1250. X.LP
  1251. XGiven the
  1252. X.I soafile
  1253. Xfor our domain (wr.tek.com):
  1254. X.RS
  1255. X.nf
  1256. X
  1257. X@    IN    SOA    wrgate.wr.tek.com.    wrap.wrgate.wr.tek.com. (
  1258. X                1    ; Serial
  1259. X                3600    ; Refresh
  1260. X                300    ; Retry
  1261. X                3600000    ; Expire
  1262. X                14400 )    ; Minimum
  1263. X        IN    NS    wrgate.wr.tek.com.
  1264. X.fi
  1265. X.RE
  1266. X.LP
  1267. XRunning
  1268. X.I "nextserial soafile"
  1269. Xwould result in the 
  1270. X.I soafile
  1271. Xlooking like:
  1272. X.RS
  1273. X.nf
  1274. X
  1275. X@    IN    SOA    wrgate.wr.tek.com.    wrap.wrgate.wr.tek.com. (
  1276. X                2    ; Serial
  1277. X                3600    ; Refresh
  1278. X                300    ; Retry
  1279. X                3600000    ; Expire
  1280. X                14400 )    ; Minimum
  1281. X        IN    NS    wrgate.wr.tek.com.
  1282. X.fi
  1283. X.RE
  1284. X.SH "SEE ALSO"
  1285. Xhostcvt(8)
  1286. X.SH BUGS
  1287. XSince the program uses regex() to find the line with "Serial" on it,
  1288. Xthe 
  1289. X.I soafile
  1290. Xshould have no other lines with that string on it.
  1291. X.SH AUTHOR
  1292. XRoger S. Southwick
  1293. X.br
  1294. Xrogers@dadla.wr.tek.com
  1295. END_OF_nextserial.8
  1296. if test 1311 -ne `wc -c <nextserial.8`; then
  1297.     echo shar: \"nextserial.8\" unpacked with wrong size!
  1298. fi
  1299. # end of overwriting check
  1300. fi
  1301. if test -f nextserial.c -a "${1}" != "-c" ; then 
  1302.   echo shar: Will not over-write existing file \"nextserial.c\"
  1303. else
  1304. echo shar: Extracting \"nextserial.c\" \(2026 characters\)
  1305. sed "s/^X//" >nextserial.c <<'END_OF_nextserial.c'
  1306. X#include <stdio.h>
  1307. X
  1308. X#ifndef lint
  1309. Xstatic char *RCSid = "$Id: nextserial.c,v 1.1 90/10/03 22:56:42 rogers Release $";
  1310. X#endif
  1311. X
  1312. X#define PAT    "Serial"
  1313. X
  1314. Xextern int errno;
  1315. Xextern char *sys_errlist[];
  1316. X#define ERR    sys_errlist[errno]
  1317. X
  1318. Xmain(argc, argv)
  1319. Xint argc;
  1320. Xchar *argv[];
  1321. X{
  1322. X    FILE *fopen();
  1323. X    char *re_comp(), *fgets(), *index(), *mktemp();
  1324. X    register char *cp;
  1325. X    register FILE *infp, *outfp;
  1326. X    register char *tmpname;
  1327. X    char buf[BUFSIZ];
  1328. X    int serial;
  1329. X
  1330. X    (void)umask(022);
  1331. X
  1332. X    if(argc != 2){
  1333. X    (void)fprintf(stderr, "usage: nextserial soafile\n");
  1334. X    exit(1);
  1335. X    }
  1336. X
  1337. X    if((cp = re_comp(PAT)) != NULL){
  1338. X    (void)fprintf(stderr, "nextserial: %s\n", cp);
  1339. X    exit(1);
  1340. X    }
  1341. X
  1342. X    tmpname = mktemp(".nxtXXXXXX");
  1343. X    (void)unlink(tmpname);
  1344. X
  1345. X    if(rename(argv[1], tmpname) == -1){
  1346. X    (void)fprintf(stderr, "nextserial: could not rename(%s, %s) - %s (%d)\n", argv[1], tmpname, ERR);
  1347. X    exit(1);
  1348. X    }
  1349. X
  1350. X    if((infp = fopen(tmpname, "r")) == NULL){
  1351. X    (void)fprintf(stderr, "nextserial: could not open %s for read\n", tmpname);
  1352. X
  1353. X    if(rename(tmpname, argv[1]) == -1)
  1354. X        (void)fprintf(stderr, "EKK! could not put %s back to %s!\n", tmpname, argv[1]);
  1355. X    exit(1);
  1356. X    }
  1357. X
  1358. X    if((outfp = fopen(argv[1], "w")) == NULL){
  1359. X    (void)fprintf(stderr, "nextserial: could not open %s for write\n", argv[1]);
  1360. X
  1361. X    if(rename(tmpname, argv[1]) == -1)
  1362. X        (void)fprintf(stderr, "EKK! could not put %s back to %s!\n", tmpname, argv[1]);
  1363. X    exit(1);
  1364. X    }
  1365. X
  1366. X    while(fgets(buf, BUFSIZ, infp) != NULL){
  1367. X    switch(re_exec(buf)){
  1368. X        case 0:
  1369. X        (void)fputs(buf, outfp);
  1370. X        break;
  1371. X        
  1372. X        case -1:
  1373. X        default:
  1374. X        (void)fprintf(stderr, "nextserial: regex internal error\n");
  1375. X        exit(1);
  1376. X        
  1377. X        case 1:
  1378. X        if((cp = index(buf, '\n')) != NULL)
  1379. X            *cp = '\0';
  1380. X
  1381. X        if(sscanf(buf, "%d", &serial) != 1){
  1382. X            (void)fprintf(stderr, "nextserial: could not decode [%s]\n", buf);
  1383. X            exit(1);
  1384. X        }
  1385. X
  1386. X        (void)fprintf(outfp, "\t\t\t\t%d\t; %s\n", ++serial, PAT);
  1387. X        break;
  1388. X    }
  1389. X    }
  1390. X    (void)fclose(outfp);
  1391. X    (void)fclose(infp);
  1392. X    (void)unlink(tmpname);
  1393. X    exit(0);
  1394. X}
  1395. END_OF_nextserial.c
  1396. if test 2026 -ne `wc -c <nextserial.c`; then
  1397.     echo shar: \"nextserial.c\" unpacked with wrong size!
  1398. fi
  1399. # end of overwriting check
  1400. fi
  1401. echo shar: End of archive 1 \(of 1\).
  1402. cp /dev/null ark1isdone
  1403. MISSING=""
  1404. for I in 1 ; do
  1405.     if test ! -f ark${I}isdone ; then
  1406.     MISSING="${MISSING} ${I}"
  1407.     fi
  1408. done
  1409. if test "${MISSING}" = "" ; then
  1410.     echo You have unpacked all 1 archives.
  1411.     rm -f ark[1-9]isdone
  1412. else
  1413.     echo You still need to unpack the following archives:
  1414.     echo "        " ${MISSING}
  1415. fi
  1416. ##  End of shell archive.
  1417. exit 0
  1418.